package com.aysafety.iotdataplatformweb.services.gas.impl;

import com.aysafety.core.DBDriver.hbase.HBaseDriver;
import com.aysafety.core.common.DateUtils;
import com.aysafety.iotdataplatformweb.dao.GasDao;
import com.aysafety.iotdataplatformweb.services.gas.GasService;
import com.safety.algorithm.eigenvalue.EigenvalueAlgorithm;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service public class GasServiceImpl implements GasService {
    private final Map<String, Object> warning = new HashMap<String, Object>() {
        {
            put("entId", "String");
            put("deviceId", "String");
            put("w1", "Double");
            put("fitness", "Double");
            put("datetime", "Date");
            put("last", "String");
        }
    };
    private final Map<String, Object> calGasStructure = new HashMap<String, Object>() {
        {
            put("entId", "String");
            put("deviceId", "String");
            put("calType", "Integer");
            put("gasWarningIndicator", "Double");
            put("gasAbsEmission", "Double");
            put("gasDivide", "Double");
            put("hoursDeviation", "Double");
            put("powerCutArea", "String");
            put("flag", "Integer");
            put("datetime", "Date");
            put("dt", "Integer");
            put("m", "Integer");
            put("n", "Integer");
        }
    };
    @Autowired GasDao gasDao;

    @Override public List<Map<String, Object>> queryCalGas(Map<String, Object> params) throws Throwable {

        long startTimeTimestamp = DateUtils.fomatDateTime(params.get("startTime").toString()).getTime();
        long endTimeTimestamp = DateUtils.fomatDateTime(params.get("endTime").toString()).getTime();
        Map<String, Object> parram = new HashMap<String, Object>();
        parram.put("tableId", params.get("entId").toString() + "." + "calgas");
        parram.put("entId", "\'" + params.get("entId").toString() + "\'");
        parram.put("deviceId", "\'" + params.get("deviceId").toString() + "\'");
        parram.put("startTime", startTimeTimestamp);
        parram.put("endTime", endTimeTimestamp);
        parram.put("size", params.get("size"));
        List<Map<String, Object>> result = gasDao.queryCalGas(parram);
        for (int i = 0; i < result.size(); i++) {
            long timestamp = (long) result.get(i).get("datetime");
            Date dateTime = DateUtils.fomatDateTime(timestamp);
            result.get(i).put("datetime", DateUtils.getTime(dateTime));
            result.get(i).put("rowkey", result.get(i).get("PK"));
            result.get(i).remove("PK");
        }
        return result;
    }

    /**
     * @Description: 综合预警
     * @Param: [mineId, startTime, endTime]
     * @return: java.util.Map<java.lang.String               ,               java.lang.Object>
     * @Author: ChengQi
     * @Date: 2019/1/11
     */
    @Override public Map<String, Object> comprehensiveWarning(String mineId, String startTime, String endTime)
        throws Throwable {
        String startRow = "";
        String endRow = "";

        startTime = DateUtils.getBeforeDayDate(-30, startTime, "yyyy-MM-dd HH:mm:ss");

        List<Map<String, Object>> conditions = new ArrayList<Map<String, Object>>();
        Map<String, Object> parram = new HashMap<String, Object>();
        parram.put("columnFamily", "warning");
        parram.put("columnId", "entId");
        parram.put("valueType", "String");
        parram.put("value", mineId);
        parram.put("symbol", "EQUAL");
        conditions.add(parram);
        parram = new HashMap<String, Object>();
        parram.put("columnFamily", "warning");
        parram.put("columnId", "datetime");
        parram.put("valueType", "Long");
        parram.put("value", DateUtils.fomatDateTime(startTime).getTime());
        parram.put("symbol", "GREATER_OR_EQUAL");
        conditions.add(parram);
        parram = new HashMap<String, Object>();
        parram.put("columnFamily", "warning");
        parram.put("columnId", "datetime");
        parram.put("valueType", "Long");
        parram.put("value", DateUtils.fomatDateTime(endTime).getTime());
        parram.put("symbol", "LESS_OR_EQUAL");
        conditions.add(parram);

        if (StringUtils.isNotBlank(startTime) && StringUtils.isBlank(startRow)) {
            endRow = String.valueOf(DateUtils.fomatDateTime(startTime).getTime());
        }
        if (StringUtils.isNotBlank(endTime)) {
            startRow = String.valueOf(DateUtils.fomatDateTime(endTime).getTime());
        }

        List<Map<String, Object>> result =
            HBaseDriver.queryData("CalWarningGas", conditions, -1, 100000, this.warning, startRow, endRow);

        double sumWi = 0.0;
        double sumRi = 0.0;
        double maxR = 0.0;
        double maxW = 0.0;
        for (int i = 0; i < result.size(); i++) {
            sumWi += Double.parseDouble(result.get(i).get("w1").toString());
            sumRi += Double.parseDouble(result.get(i).get("fitness").toString());
            maxR = maxR > Double.parseDouble(result.get(i).get("fitness").toString()) ?
                maxR :
                Double.parseDouble(result.get(i).get("fitness").toString());
            maxW = maxW > Double.parseDouble(result.get(i).get("w1").toString()) ?
                maxW :
                Double.parseDouble(result.get(i).get("w1").toString());
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("R", maxR);
        map.put("W", EigenvalueAlgorithm.divide(sumWi * maxR, sumRi * maxW, 0));
        map.put("result", result);
        return map;
    }

    private List<Map<String, Object>> getCond(Map<String, Object> params) {
        List<Map<String, Object>> conditions = new ArrayList<Map<String, Object>>();
        Map<String, Object> parram = new HashMap<String, Object>();

        if (params.containsKey("entId")) {
            parram.put("columnFamily", "gasEmission");
            parram.put("columnId", "entId");
            parram.put("valueType", "String");
            parram.put("value", params.get("entId"));
            parram.put("symbol", "EQUAL");
            conditions.add(parram);
        }

        if (params.containsKey("deviceId")) {
            parram = new HashMap<String, Object>();
            parram.put("columnFamily", "gasEmission");
            parram.put("columnId", "deviceId");
            parram.put("valueType", "String");
            parram.put("value", params.get("deviceId").toString());
            parram.put("symbol", "EQUAL");
            conditions.add(parram);
        }


        if (params.containsKey("startTime")) {
            parram = new HashMap<String, Object>();
            parram.put("columnFamily", "gasEmission");
            parram.put("columnId", "datetime");
            parram.put("valueType", "Long");
            parram.put("value", DateUtils.fomatDateTime(params.get("startTime").toString()).getTime());
            parram.put("symbol", "GREATER_OR_EQUAL");
            conditions.add(parram);
        }

        if (params.containsKey("endTime")) {
            parram = new HashMap<String, Object>();
            parram.put("columnFamily", "gasEmission");
            parram.put("columnId", "datetime");
            parram.put("valueType", "Long");
            parram.put("value", DateUtils.fomatDateTime(params.get("endTime").toString()).getTime());
            parram.put("symbol", "LESS_OR_EQUAL");
            conditions.add(parram);
        }

        return conditions;
    }

    @Override public long countByCalGas(Map<String, Object> params) throws Throwable {

        long startTimeTimestamp = DateUtils.fomatDateTime(params.get("startTime").toString()).getTime();
        long endTimeTimestamp = DateUtils.fomatDateTime(params.get("endTime").toString()).getTime();
        Map<String, Object> parram = new HashMap<String, Object>();
        parram.put("tableId", params.get("entId").toString() + "." + "calgas");
        parram.put("entId", "\'" + params.get("entId").toString() + "\'");
        parram.put("deviceId", "\'" + params.get("deviceId").toString() + "\'");
        parram.put("startTime", startTimeTimestamp);
        parram.put("endTime", endTimeTimestamp);
        return gasDao.countCalGas(parram);
    }

    @Override public long countByGas(String mineId, String deviceId, String startTime, String endTime, int timeSpan,
        String timeUnit) throws Throwable {
        long startTimeTimestamp = DateUtils.fomatDateTime(startTime).getTime();
        long endTimeTimestamp = DateUtils.fomatDateTime(endTime).getTime();
        Map<String, Object> parram = new HashMap<String, Object>();
        parram.put("tableId", mineId + "." + "GASREALTIME");
        parram.put("entId", "\'" + mineId + "\'");
        parram.put("deviceId", "\'" + deviceId + "\'");
        parram.put("startTime", startTimeTimestamp);
        parram.put("endTime", endTimeTimestamp);
        return gasDao.countByGas(parram);
    }

    @Override public List<Map<String, Object>> queryRealTimeByGas(String mineId, String deviceId, String startTime,
        String endTime, int timeSpan, String timeUnit, int page, int size, String startRow) throws Throwable {
        long startTimeTimestamp = DateUtils.fomatDateTime(startTime).getTime();
        long endTimeTimestamp = DateUtils.fomatDateTime(endTime).getTime();
        Map<String, Object> parram = new HashMap<String, Object>();
        parram.put("tableId", mineId + "." + "GASREALTIME");
        parram.put("entId", "\'" + mineId + "\'");
        parram.put("deviceId", "\'" + deviceId + "\'");
        parram.put("startTime", startTimeTimestamp);
        parram.put("endTime", endTimeTimestamp);
        //parram.put("size", size);

        List<Map<String, Object>> result = gasDao.queryRealTimeByGas(parram);
        for (int i = 0; i < result.size(); i++) {
            long timestamp = (long) result.get(i).get("datetime");
            Date dateTime = DateUtils.fomatDateTime(timestamp);
            result.get(i).put("datetime", DateUtils.getTime(dateTime));
            result.get(i).put("rowkey", result.get(i).get("PK"));
            result.get(i).remove("PK");
        }
        return result;
    }
}
